﻿using System;
using System.Buffers.Text;
using System.Runtime.InteropServices;
using Unity.Mathematics;
using Unity.Netcode;
using Unity.Netcode.Components;
using UnityEngine;

public class Slime : NetworkBehaviour
{
    [Header("Common")]
    [SerializeField] SlimeData data;

    int currentHealth;
    
    bool isFacingLeft = false;
    
    NetworkAnimator networkAnimator;
    SpriteRenderer spriteRenderer;
    Transform target;

    public int Health => currentHealth;


    public override void OnNetworkSpawn()
    {
        spriteRenderer = GetComponentInChildren<SpriteRenderer>();
        networkAnimator = GetComponent<NetworkAnimator>();
        if(IsOwner)
            currentHealth = data.MaxHealth;
    }

    void Update()
    {
        if (!IsOwner)
            return;

        if (!FindTarget())
            return;

        if (transform.position.x < target.position.x)
            isFacingLeft = false;
        else if (transform.position.x > target.position.x)
            isFacingLeft = true;
        
        if (isFacingLeft)
            spriteRenderer.transform.localScale = new Vector2(-1, 1);
        else
            spriteRenderer.transform.localScale = new Vector2(1, 1);

        transform.position = Vector2.MoveTowards(
            transform.position,
            target.position,
            data.Speed * Time.deltaTime
            );
    }

    bool FindTarget()
    {        
        foreach(var e in NetworkManager.ConnectedClientsList)
        {
            Transform targetTF=e.PlayerObject.transform;
            if (!targetTF.gameObject.activeInHierarchy)
                continue;
            if (target == null || !target.gameObject.activeInHierarchy)
                target = targetTF;
            else
            {
                if (Vector2.SqrMagnitude(target.transform.position - transform.position) > Vector2.SqrMagnitude(targetTF.position - transform.position))
                {
                    target=targetTF;
                }
            }
        }
        return target!=null && target.gameObject.activeInHierarchy;
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (!IsOwner)
            return;
        if(collision.TryGetComponent<Knight>(out Knight knight))
        {            
            OnAttack(knight);
        }
    }

    void OnAttack(Knight knight)
    {
        knight.OnHit(data.ATK);
        Vector3 direction = (transform.position - knight.transform.position).normalized;
        transform.position = Vector2.MoveTowards(transform.position, transform.position + direction, 0.5f);
    }

    public void OnHit(int damage,ulong attackerID)
    {
        HitRpc(damage,attackerID);
    }

    [Rpc(SendTo.Server)]
    void HitRpc(int damage, ulong attackerID)
    {
        currentHealth -= damage;
        networkAnimator.SetTrigger("OnHit");

        if (currentHealth <= 0)
        {
            NotifyKillerRpc(RpcTarget.Single(attackerID,RpcTargetUse.Temp));
            OnDeath();
        }            
    }

    [Rpc(SendTo.SpecifiedInParams)]
    void NotifyKillerRpc(RpcParams rpcParams)
    {
        Knight.Instance.Money+= data.DeathDrop;        
    }

    void OnDeath()
    {                
        NetworkObject.Despawn();
    }
}